package nl.cypherpunk.proLearner.smtp;

import net.automatalib.words.Alphabet;
import net.automatalib.words.Word;
import net.automatalib.words.impl.Alphabets;
import nl.cypherpunk.proLearner.Common;
import nl.cypherpunk.proLearner.fuzzing.SUT;
import nl.cypherpunk.proLearner.mealyDot.MealyState;

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static nl.cypherpunk.proLearner.Common.byteArrayToInt;
import static nl.cypherpunk.proLearner.Common.readFromFile;

public class SMTPSUL implements SUT<String, String> {
    Alphabet<String> alphabet;
    public SMTPTestService smtp;
    public SMTPSUL(SMTPConfig config) throws Exception {
        //alphabet = Alphabets.fromList(Arrays.asList(config.alphabet.split(" ")));

        smtp = new SMTPTestService();

        smtp.setTarget(config.target);
        smtp.setHost(config.host);
        smtp.setPort(config.port);
        smtp.setCommand(config.cmd);
        smtp.setRestartTarget(config.restart);
        smtp.setReceiveMessagesTimeout(config.timeout);
        smtp.setConsoleOutput(config.console_output);
        smtp.setRedirectFile(config.redirectFile);
        //tls.setCoverageCmd(config.coverage_cmd);
        smtp.setOutputDir(config.output_dir);
        smtp.setVersion(config.version);
        File outputDir = new File(smtp.outputDir + File.separator +"Seed");
        outputDir.mkdirs();
        smtp.start();
    }

    public boolean addMapper(String type, byte[] message){
        return smtp.addMapper(type,message);
    }

    public boolean delMapper(String subtype){
        return smtp.delMapper(subtype);
    }

    public Map<String, Integer> getSubtypes()
    {
        return smtp.subtypes;
    }

    public int getTotalNum()
    {
        return smtp.totalExecs;
    }
    public void saveMapper()
    {
        smtp.saveMapper();
    }
    @Override
    public String messageToSymbol(byte[] message)  {
        String m="";
        try{
            m = new String(message,"utf-8");
        }
        catch(Exception e){
            e.printStackTrace();
        }
        String[] tmp = m.split(" ");
        tmp = tmp[0].split("\r\n");
        Pattern p = Pattern.compile("\\s*|\t|\r|\n");
        Matcher result = p.matcher(tmp[0]);
        return result.replaceAll("");
    }

    @Override
    public int getIndexOfSymbol(byte[] message){
        String m="";
        try{
            m = new String(message,"utf-8");
        }
        catch(Exception e){
            e.printStackTrace();
        }
        String[] tmp = m.split(" ");
        return tmp[0].length()+1;
    }

    @Override
    public Alphabet<String> getAlphabet() {
        return Alphabets.fromList(smtp.symbols);
    }

    public void exit()
    {
        smtp.close();
    }

    public boolean canFork() {
        return false;
    }
    //change by pany

    public int getCoverage() throws IOException {
        return 0;
    }

    public String sendFuzzingMessage(byte[] message) throws Exception
    {
        return smtp.sendFuzzingMessage(message);
    }

    public byte[] getCurrent(){
        return smtp.currentCase.get(smtp.currentCase.size()-1);
    }

    @Override
    public String step(String symbol) {
        String result = null;
        try {
            result = smtp.processSymbol(symbol);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @Override
    public void pre() {
        try {
            smtp.reset();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(0);
        }
    }

    @Override
    public void post() {
        try {
            smtp.closeSocket();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(0);
        }
    }
}
